package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.*;
import com.example.demo.exception.bizException.BizException;
import com.example.demo.mapper.PatentMapper;
import com.example.demo.service.*;
import com.example.demo.util.ExcelUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cy
 * @since 2020-10-09
 */
@Slf4j
@Service
public class PatentServiceImpl extends ServiceImpl<PatentMapper, Patent> implements PatentService {

    @Autowired
    private PPhotoService pPhotoService;
    @Autowired
    private FileService fileService;
    @Autowired
    private InformationService informationService;
    @Autowired
    private CollectService collectService;

    @Override
    public Page<Patent> listAchievesByPage(int page, int pageSize, Integer userId, String patentName, String patentType, String year, Integer state) {
        log.info("正在执行分页查询achieve: page = {} pageSize = {} userId = {} patentName={} state={}", page, pageSize, userId, patentName, state);
        QueryWrapper<Patent> queryWrapper = new QueryWrapper<Patent>().eq(userId != null, "u_id", userId)
                .eq(patentType.length() != 0, "patent_type", patentType)
                .eq(state != null, "state", state)
                .eq(year.length() != 0, "year", year)
                .and(patentName.length() != 0, w -> w.like(patentName.length() != 0, "patent_name", patentName))
                .or(patentName.length() != 0, w -> w.like(patentName.length() != 0, "patent_man", patentName))
                .or(patentName.length() != 0, w -> w.like(patentName.length() != 0, "patent_num", patentName))
                .orderByDesc("public_time");
        Page<Patent> result = super.page(new Page<>(page, pageSize), queryWrapper);
        log.info("分页查询patent完毕: 结果数 = {} ", result.getRecords().size());
        return result;
    }

    @Override
    public Patent getPatentById(int id) {
        log.info("正在查询patent中id为{}的数据", id);
        Patent patent = super.getById(id);
        log.info("查询id为{}的patent{}", id, (null == patent ? "无结果" : "成功"));
        return patent;
    }

    @Override
    public Patent getPatentByPatentNum(String patentNum) {
        Patent patent = super.getOne(new QueryWrapper<Patent>().eq("patent_num", patentNum));
        return patent;
    }

    @Override
    public int insertPatent(Patent patent) {
        log.info("正在插入patent");
        if (super.save(patent)) {
            log.info("插入patent成功,id为{}", patent.getPatentId());
            return patent.getPatentId();
        } else {
            log.error("插入patent失败");
            throw new BizException("添加失败");
        }
    }

    @Transactional
    @Override
    public int deletePatentById(int id, int userId) {
        log.info("正在删除id为{}的patent", id);
        Patent patentById = this.getPatentById(id);
        if (!patentById.getUId().equals(userId)) {
            log.info("该{}专利不属于该{}用户", patentById.getUId(), userId);
            throw new BizException("该专利不属于该用户");
        }
        List<PPhoto> list = pPhotoService.getPPhotoByPId(id);
        for (PPhoto pPhoto : list) {
            fileService.delete(pPhoto.getPhotoName());
        }
        collectService.deleteCollectByForeignId(id, Collect.PATENT_TYPE);
        if (super.removeById(id)) {
            log.info("删除id为{}的patent成功", id);
            return id;
        } else {
            log.error("删除id为{}的patent失败", id);
            throw new BizException("删除失败[id=" + id + "]");
        }
    }

    @Override
    public int updatePatent(Patent patent) {
        patent.setState(Achieve.CHECK);
        log.info("正在更新id为{}的patent", patent.getPatentId());
        if (super.updateById(patent)) {
            log.info("更新d为{}的patent成功", patent.getPatentId());
            return patent.getPatentId();
        } else {
            log.error("更新id为{}的patent失败", patent.getPatentId());
            throw new BizException("更新失败[id=" + patent.getPatentId() + "]");
        }
    }

    @Override
    public int checkPatent(Patent patent) {
        log.info("patent中id为{}正在通过审核", patent.getPatentId());
        Patent inPatent = super.getById(patent.getPatentId());
        //设置给用户的消息通知
        Information information = new Information();
        information.setTime(LocalDateTime.now());
        information.setUserId(inPatent.getUId());
        //判断专利审核状态
        if (patent.getState() == Demand.NO_PASS) {
            information.setMessage("尊敬的用户您好，您的一个专利审核未通过，您可以对专利内容进行修改后再次提交申请或者联系管理员。");
        } else if (patent.getState() == Demand.PASS) {
            information.setMessage("尊敬的用户您好，您的一个专利审核已通过。");
        } else {
            throw new BizException("专利状态错误");
        }
        informationService.insertInformation(information);
        if (super.updateById(patent)) {
            log.info("审核id为{}的patent成功,通过与否{}", patent.getPatentId(), patent.getState() == Demand.PASS);
            return patent.getPatentId();
        } else {
            log.error("审核id为{}patent失败", patent.getPatentId());
            throw new BizException("更新失败[id=" + patent.getPatentId() + "]");
        }
    }

    @SneakyThrows
    @Override
    public int importPatent(String fileName, MultipartFile file, User user) throws IOException {
        log.info("开始导入文件，批量增加专利");
        if (!ExcelUtil.validateExcel(fileName)) {
            log.error("上传文件格式错误,导入专利失败");
            throw new BizException("上传文件格式错误");
        }
        //03和07之后的文件命名不一样，需分别开来
        boolean isExcel2003 = false;
        if (ExcelUtil.isExcel2003(fileName)) {
            isExcel2003 = true;
        }
        InputStream is = file.getInputStream();
        Workbook wb = null;
        //根据不同的文件生成不同的对象
        if (isExcel2003) {
            wb = new HSSFWorkbook(is);
        } else {
            wb = new XSSFWorkbook(is);
        }
        Sheet sheet = wb.getSheetAt(0);
        List<Patent> patents = new ArrayList<>();
        /*
        获得图片
        Map<String, PictureData> maplist=null;
        if (isExcel2003){
            maplist = ExcelUtil.getPictures1((HSSFSheet) sheet);
        }else{
            maplist = ExcelUtil.getPictures2((XSSFSheet) sheet);
        }
         */
        //r从1开始，因为数据是从第二行开始记录
        for (int r = 1; r <= sheet.getLastRowNum(); r++) {
            Row row = sheet.getRow(r);
            if (row == null) {
                continue;
            }
            Patent patent = new Patent();
            //从上往下是 专利申请号、专利名称、专利类型、专利作者、专利详情、专利年限、申请日、公开日
            if (row.getCell(0) == null) {
                continue;
            }
            patent.setPatentNum(row.getCell(0).getStringCellValue());
            patent.setPatentName(row.getCell(1) != null ? row.getCell(1).getStringCellValue() : "");
            patent.setPatentType(row.getCell(2) != null ? row.getCell(2).getStringCellValue() : "");
            patent.setPatentMan(row.getCell(3) != null ? row.getCell(3).getStringCellValue() : "");
            patent.setPatentDetails(row.getCell(4) != null ? row.getCell(4).getStringCellValue() : "");
            patent.setYear(Integer.valueOf(row.getCell(5).getStringCellValue()));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            if (row.getCell(6) != null && row.getCell(6).getCellType() != CellType.BLANK) {
                if (row.getCell(7).getCellType() == CellType.STRING) {
                    patent.setApplyTime(ExcelUtil.UDateToLocalDate(sdf.parse(row.getCell(6).getStringCellValue())));
                } else {
                    patent.setApplyTime(ExcelUtil.UDateToLocalDate(row.getCell(6).getDateCellValue()));
                }
            }
            if (row.getCell(7) != null && row.getCell(7).getCellType() != CellType.BLANK) {
                if (row.getCell(7).getCellType() == CellType.STRING) {
                    patent.setPublicTime(ExcelUtil.UDateToLocalDate(sdf.parse(row.getCell(7).getStringCellValue())));
                } else {
                    patent.setPublicTime(ExcelUtil.UDateToLocalDate(row.getCell(7).getDateCellValue()));
                }
            }
            patents.add(patent);
            System.out.println(r);
        }
        for (Patent patent : patents) {
            //如果是管理员导入则审核状态设置为已通过
            if (user.getState() == User.ADMIN) {
                patent.setState(Achieve.PASS);
            }
            Patent isHave = this.getPatentByPatentNum(patent.getPatentNum());
            if (isHave != null) {
                //如果存在此专利则覆盖
                patent.setPatentId(isHave.getPatentId());
                super.updateById(patent);
            } else {
                patent.setUId(user.getUserId());
                super.save(patent);
            }
        }
        log.info("导入专利成功，共导入{}条数据", patents.size());
        return patents.size();
    }

    @Override
    public int UncheckedNum() {
        log.info("正在查询未审核的数量");

    /*    LambdaQueryWrapper<Patent> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(Patent::getState);
        return  this.getBaseMapper().selectObjs(lambdaQueryWrapper).stream()
                .map(o -> (Integer) o).collect(Collectors.toList()).size(); //getBaseMapper().selectBatchIds(Arrays.asList(0));  // (List<Achieve>) super.getMap();
*/
        QueryWrapper<Patent> queryWrapper = new QueryWrapper<Patent>().eq("state", 0);
        List<Patent> patentList = this.getBaseMapper().selectList(queryWrapper);
        return patentList.size();
    }


}
